package org.equivalence.server;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;

import org.equivalence.common.PropertiesReader;
import org.equivalence.server.common.IServer;
import org.equivalence.server.sockets.SocketsUpdateServer;

/**
 * This is the class through which applications can instantiate and get a hold 
 * of the server. The server returned is of type {@link IServer}, which is the 
 * interface that should be implemented by any class that wishes to provide a
 * mechanism through which clients may access it. Current examples include over
 * sockets and using web services.
 * 
 * @author Jonathan Giles
 */
public class ServerFactory {
	private static IServer server;
	private static PropertiesReader properties = null;
	
	/**
	 * This will return the single server instance. If it does not exist,
	 * it will be instantiated as part of calling this method.
	 */
	public static IServer getServer() {
		if (server == null) {
			// trying to initialise the proper server
			initServer();
		}
		
		return server;
	}

	private static void initServer() {
		// getting the config file
		File serverProperties = new File("serverConfig.pro");
		
		// and then getting it to be parsed
		try {
			InputStream propertiesStream = serverProperties.toURI().toURL().openStream();
			properties = new PropertiesReader(propertiesStream);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		// if properties is null, shut down the server
		if (properties == null) {
			System.out.println("Can't load serverProperties.xml file. Shutting server down.");
			shutdownServer();
		}
		
		// determining the server type and loading it
		String serverType = properties.getProperty("server.type", "sockets");
		if ("sockets".equals(serverType)) {
			loadSocketsServer();
		} else if ("webservice".equals(serverType)) {
			loadWebServicesServer();
		} else {
			System.out.println("server.type not set or is invalid: " + serverType);
		}
		
		if (server == null) {
			shutdownServer();
		}
		
	}

	private static void loadWebServicesServer() {
		System.out.println("webservice server type not presently implemented");		
	}

	private static void loadSocketsServer() {
		int serverPort = Integer.parseInt(properties.getProperty("server.port", "1984"));
		if (serverPort > 0 && serverPort < 65535) {
			server = new SocketsUpdateServer(serverPort);
		} else {
			System.out.println("server.port not set or is invalid: " + serverPort);
		}		
	}
	
	private static void shutdownServer() {
		System.out.println("Shutting down server");
		System.exit(-1);
	}
}
